-- Lua Battle System - 配置加载工具

local Logger = require("utils.logger")
local TableUtils = require("utils.table_utils")
local Errors = require("utils.errors")

local ConfigLoader = {
    -- 配置缓存
    configs = {},
    -- 配置文件依赖关系
    dependencies = {},
    -- 配置文件元数据（修改时间等）
    metadata = {},
    -- 配置路径
    config_path = "../res/data/config/",
    -- 缓存配置
    cache_config = {
        enable_caching = true,
        check_file_modification = false,
        cache_ttl = 3600 -- 缓存过期时间（秒），0表示永不过期
    },
    -- 热重载配置
    hot_reload_config = {
        enable_hot_reload = false,
        check_interval = 5, -- 检查间隔（秒）
        last_check_time = 0
    },
    -- 热重载定时器
    hot_reload_timer = nil
}

-- 初始化配置加载器
function ConfigLoader:init(config)
    if config then
        if config.config_path then
            self.config_path = config.config_path
        end
        if config.cache_config then
            for key, value in pairs(config.cache_config) do
                if self.cache_config[key] ~= nil then
                    self.cache_config[key] = value
                end
            end
        end
        if config.hot_reload_config then
            for key, value in pairs(config.hot_reload_config) do
                if self.hot_reload_config[key] ~= nil then
                    self.hot_reload_config[key] = value
                end
            end
        end
    end
    
    Logger.info("配置加载器初始化完成")
    Logger.info("配置路径: " .. self.config_path)
    Logger.info("缓存配置: " .. TableUtils.tostring(self.cache_config))
    Logger.info("热重载配置: " .. TableUtils.tostring(self.hot_reload_config))
    
    -- 初始化热重载
    if self.hot_reload_config.enable_hot_reload then
        self:enable_hot_reload()
    end
end

-- 检查配置文件变化
function ConfigLoader:check_config_changes()
    local current_time = os.time()
    
    -- 检查是否达到检查间隔
    if current_time - self.hot_reload_config.last_check_time < self.hot_reload_config.check_interval then
        return
    end
    
    self.hot_reload_config.last_check_time = current_time
    
    Logger.debug("检查配置文件变化...")
    local changed_files = {}
    
    -- 检查所有已加载的配置文件
    for file_name, config in pairs(self.configs) do
        local full_path = self.config_path .. file_name
        local current_mtime = get_file_modification_time(full_path)
        
        -- 检查文件是否被修改
        if self.metadata[file_name] and current_mtime ~= self.metadata[file_name].modification_time then
            table.insert(changed_files, file_name)
        end
    end
    
    -- 重新加载变化的配置文件
    for _, file_name in ipairs(changed_files) do
        Logger.info("配置文件已修改，重新加载: " .. file_name)
        self:reload_config(file_name)
    end
    
    return changed_files
end

-- 启用热重载
function ConfigLoader:enable_hot_reload()
    if self.hot_reload_config.enable_hot_reload then
        Logger.warn("热重载已启用")
        return
    end
    
    self.hot_reload_config.enable_hot_reload = true
    self.hot_reload_config.last_check_time = os.time()
    
    Logger.info("热重载已启用，检查间隔: " .. self.hot_reload_config.check_interval .. "秒")
end

-- 禁用热重载
function ConfigLoader:disable_hot_reload()
    if not self.hot_reload_config.enable_hot_reload then
        Logger.warn("热重载已禁用")
        return
    end
    
    self.hot_reload_config.enable_hot_reload = false
    
    if self.hot_reload_timer then
        -- 停止定时器
        -- 注意：Lua标准库中没有内置定时器，这里需要根据实际环境实现
        -- 例如使用coroutine或外部库
        self.hot_reload_timer = nil
    end
    
    Logger.info("热重载已禁用")
end

-- 更新热重载配置
function ConfigLoader:update_hot_reload_config(config)
    if config then
        for key, value in pairs(config) do
            if self.hot_reload_config[key] ~= nil then
                self.hot_reload_config[key] = value
            end
        end
        Logger.info("热重载配置已更新: " .. TableUtils.tostring(self.hot_reload_config))
    end
end

-- 运行热重载检查
function ConfigLoader:run_hot_reload_check()
    if not self.hot_reload_config.enable_hot_reload then
        return
    end
    
    return self:check_config_changes()
end

-- 获取文件修改时间
local function get_file_modification_time(file_path)
    local file = io.open(file_path, "r")
    if not file then
        return 0
    end
    local modification_time = file:seek("end")
    file:close()
    return modification_time
end

-- 加载配置文件
function ConfigLoader:load_config(file_name)
    local full_path = self.config_path .. file_name
    Logger.debug("加载配置文件: " .. full_path)
    
    -- 检查文件是否存在
    local file = io.open(full_path, "r")
    if not file then
        Logger.error("配置文件不存在: " .. full_path)
        return nil, Errors:create(Errors.CONFIG_ERROR, "配置文件不存在: " .. file_name)
    end
    file:close()
    
    -- 加载配置文件
    local success, config = pcall(dofile, full_path)
    if not success then
        Logger.error("加载配置文件失败: " .. full_path .. ", 错误: " .. tostring(config))
        return nil, Errors:create(Errors.CONFIG_ERROR, "加载配置文件失败: " .. file_name, tostring(config))
    end
    
    -- 保存配置到缓存
    if self.cache_config.enable_caching then
        -- 保存配置
        self.configs[file_name] = config
        
        -- 保存元数据
        self.metadata[file_name] = {
            modification_time = get_file_modification_time(full_path),
            load_time = os.time(),
            dependencies = {}
        }
        
        -- 记录配置文件依赖关系（如果配置中有dependencies字段）
        if config.dependencies then
            self.dependencies[file_name] = config.dependencies
            for _, dep_file in ipairs(config.dependencies) do
                -- 确保依赖文件也被加载
                self:get_config(dep_file)
            end
        end
    end
    
    Logger.debug("配置文件加载成功: " .. full_path)
    return config
end

-- 检查配置是否过期
function ConfigLoader:is_config_expired(file_name)
    if not self.cache_config.enable_caching then
        return true
    end
    
    local meta = self.metadata[file_name]
    if not meta then
        return true
    end
    
    -- 检查TTL
    if self.cache_config.cache_ttl > 0 then
        if os.time() - meta.load_time > self.cache_config.cache_ttl then
            return true
        end
    end
    
    -- 检查文件修改时间
    if self.cache_config.check_file_modification then
        local full_path = self.config_path .. file_name
        local current_mtime = get_file_modification_time(full_path)
        if current_mtime ~= meta.modification_time then
            return true
        end
    end
    
    return false
end

-- 获取配置
function ConfigLoader:get_config(file_name)
    -- 检查缓存是否启用
    if not self.cache_config.enable_caching then
        return self:load_config(file_name)
    end
    
    -- 检查配置是否存在且未过期
    if self.configs[file_name] and not self:is_config_expired(file_name) then
        return self.configs[file_name]
    end
    
    -- 加载或重新加载配置
    return self:load_config(file_name)
end

-- 合并配置
function ConfigLoader:merge_config(file_name, new_config)
    local current_config = self:get_config(file_name)
    if not current_config then
        current_config = {}
    end
    
    local merged_config = TableUtils.merge(current_config, new_config)
    
    -- 更新缓存
    if self.cache_config.enable_caching then
        self.configs[file_name] = merged_config
        
        -- 更新元数据
        if self.metadata[file_name] then
            self.metadata[file_name].load_time = os.time()
        end
    end
    
    return merged_config
end

-- 重新加载配置
function ConfigLoader:reload_config(file_name)
    Logger.debug("重新加载配置文件: " .. file_name)
    
    -- 移除配置缓存
    self.configs[file_name] = nil
    self.metadata[file_name] = nil
    
    -- 重新加载配置
    local config, error = self:load_config(file_name)
    
    -- 如果有依赖关系，重新加载依赖的配置
    if self.dependencies[file_name] then
        for _, dep_file in ipairs(self.dependencies[file_name]) do
            self:reload_config(dep_file)
        end
    end
    
    return config, error
end

-- 重新加载所有配置
function ConfigLoader:reload_all()
    Logger.info("重新加载所有配置文件")
    local files = {}
    
    -- 保存当前加载的配置文件列表
    for file_name in pairs(self.configs) do
        table.insert(files, file_name)
    end
    
    -- 清空缓存
    self.configs = {}
    self.metadata = {}
    
    -- 重新加载所有配置
    local loaded_count = 0
    local error_count = 0
    
    for _, file_name in ipairs(files) do
        local success = self:load_config(file_name)
        if success then
            loaded_count = loaded_count + 1
        else
            error_count = error_count + 1
        end
    end
    
    Logger.info("所有配置文件重新加载完成，成功: " .. loaded_count .. ", 失败: " .. error_count)
    return loaded_count, error_count
end

-- 清除配置缓存
function ConfigLoader:clear_cache(file_name)
    if file_name then
        -- 清除指定配置的缓存
        self.configs[file_name] = nil
        self.metadata[file_name] = nil
        Logger.debug("清除配置缓存: " .. file_name)
    else
        -- 清除所有配置缓存
        self.configs = {}
        self.metadata = {}
        Logger.info("清除所有配置缓存")
    end
end

-- 获取配置文件依赖关系
function ConfigLoader:get_dependencies(file_name)
    return self.dependencies[file_name] or {}
end

-- 获取配置元数据
function ConfigLoader:get_metadata(file_name)
    return self.metadata[file_name]
end

-- 加载角色配置
function ConfigLoader:load_character_config(character_id)
    local file_name = "characters/" .. character_id .. ".lua"
    return self:get_config(file_name)
end

-- 加载技能配置
function ConfigLoader:load_skill_config(skill_id)
    local file_name = "skills/" .. skill_id .. ".lua"
    return self:get_config(file_name)
end

-- 加载物品配置
function ConfigLoader:load_item_config(item_id)
    local file_name = "items/" .. item_id .. ".lua"
    return self:get_config(file_name)
end

-- 导出模块
return ConfigLoader